package com.tanhua.manage.service;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.manage.domain.Admin;
import com.tanhua.manage.exception.BusinessException;
import com.tanhua.manage.mapper.AdminMapper;
import com.tanhua.manage.vo.CommonResponse;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * service层代码
 *  在mybatis-plus中支持，类似mapper的写法，只需要继承
 *      <Mapper接口，实体类>
 */
@Service
public class AdminService extends ServiceImpl<AdminMapper, Admin> {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Value("${tanhua.secret}")
    private String secret;

    //存入图形验证码到redis中
    public void saveCap(String uuid, String code) {
        String key = "MANAGE_CAP_"+uuid;
        redisTemplate.opsForValue().set(key,code, Duration.ofMinutes(2));
    }

    /**
     * 登录
     *      username password verificationCode uuid
     */
    public ResponseEntity login(Map<String, String> map) {
        String username= map.get("username");
        String password= map.get("password");
        String verificationCode= map.get("verificationCode");
        String uuid= map.get("uuid");

        if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            throw  new BusinessException("用户名或者密码为空");
        }

        if(StringUtils.isEmpty(verificationCode) || StringUtils.isEmpty(uuid)) {
            throw  new BusinessException("验证码为空");
        }

        //1、获取redis中的验证码并比较
        String key = "MANAGE_CAP_"+uuid;
        String value = redisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(value) || !value.equals(verificationCode)) {
            throw  new BusinessException("验证码校验失败");
        }

        redisTemplate.delete(key);
        //2、通过用户名查询登录的Admin对象，比较
        Admin admin = query().eq("username", username).one();
        if(admin == null) {
            throw  new BusinessException("用户名错误");
        }

        //3、判断对象中的密码和输入密码是否一致
        if(!admin.getPassword().equals(SecureUtil.md5(password))) {
            throw  new BusinessException("密码错误");
        }

        //4、生成token
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("username", username);
        claims.put("id", admin.getId());
        String token =  Jwts.builder().setClaims(claims) //设置响应数据体
                        .signWith(SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
                        .compact();
        //5、将用户对象存入redis中
        String adminStr = JSON.toJSONString(admin);
        redisTemplate.opsForValue().set("MANAGE_TOKEN_"+token, adminStr,Duration.ofHours(1));

        //6、构造返回值
        Map result = new HashMap();
        result.put("token",token);
        return ResponseEntity.ok(result);
    }
    /**
     * 通过token获取admin对象
     */
    public Admin findByToken(String token) {
        String key = "MANAGE_TOKEN_"+token;
        String adminStr = redisTemplate.opsForValue().get(key);
        return JSON.parseObject(adminStr,Admin.class);
    }


    //退出登录
    public ResponseEntity logout(String token) {
        String key = "MANAGE_TOKEN_"+token;
        redisTemplate.delete(key);
        return ResponseEntity.ok(null);
    }
}
